package it.poste.il.compensatore.aop;

import it.poste.il.compensatore.utilities.LoggerCompensatore;

import java.util.Arrays;
import java.util.Date;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Aspect;

/**
 * Class that is responsible for logging the execution of the methods.
 */
@SuppressWarnings("unused")
@Aspect
public class LogAroundAspect {

	/**
	 * The Log Factory.
	 */
	private static LoggerCompensatore loggerF;

	/**
	 * Method that returns the Log Factory.
	 * @return LogFactory The Log Factory.
	 */
	public LoggerCompensatore getLoggerF() {
		return loggerF;
	}

	/**
	 * Method that sets the Log Factory.
	 * @param LogFactory Log Factory to set.
	 * @return void
	 */
	public void setLoggerF(LoggerCompensatore loggerF) {
		this.loggerF = loggerF;
	}

	/**
	 * Logs first and after method's invocation and operations.
	 * Applied to all public methods of classes contained in the package of the hierarchy it.
	 * @param ProceedingJoinPoint Join-Point for the aspect.
	 * @return Object The object returned.
	 */
	//@Around("execution(* it..*(..))")
	//TODO Aggiustare l'around di aop
	public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
		LoggerCompensatore logger = (LoggerCompensatore) loggerF.getLogger(this);
		// Log prima dell'invocazione del metodo
		logger.info("[" + new Date() + "]\n\t" 
				+  pjp.getTarget().getClass() + "."  +  pjp.getSignature().getName()
				+  "\n\tArguments: "+ Arrays.toString(pjp.getArgs()));
		
		Object result = null;
		try {
			// Invocazione metodo
			result = pjp.proceed();
		} catch (Exception ex) {
			logger.error("\tError: " + pjp.getSignature().getName());
		}
		
		//Operazioni dopo l'esecuzione
		logger.info("\tResult: "+ result);			
		return result;
	}
}
